<template>
	<div class="container">
		<div class="chat-box">
			<div class="left">
				<div class="head">
					<div class="title-left">客服咨询</div>
					<div class="retract-right" @click="state.isRetract = !state.isRetract">
						<SvgIcon v-if="state.isRetract" name="ele-Fold" :size="22" color="var(--el-color-primary)" />
						<SvgIcon v-else name="ele-Expand" :size="22" color="var(--el-color-primary)" />
					</div>
				</div>
				<ChatContent
					:chatting-record-list="state.chattingRecordList"
					@sendMessageReq="sendMessageReq"
					@fileSendMessage="fileSendMessage"
					:identity="EIdentity.Customer"
					v-model:content="state.content"
				/>
			</div>
			<div class="right" :style="[!state.isRetract ? 'width:0px;' : '']">
				<template v-if="state.isRetract">
					<img class="avatar" src="../../../assets/icon/default-avatar.svg" alt="" />
					<div class="title">人工客服</div>
					<div class="address"><img src="../../../assets/icon/location.svg" alt="" /><span>江苏省南京市江宁区</span></div>
					<div class="domain-name"><img src="../../../assets/icon/domain-name.svg" alt="" /><span>www.baidu.com</span></div>
				</template>
			</div>
		</div>
	</div>
</template>
<script lang="ts" setup>
import { ws } from '/@/utils/websocket';
import ChatContent from './cpn/chatContent.vue';
import { Base64 } from '/@/utils/b64';
import { httpReqeustApi } from '/@/api/linxyun/base/index.ts';
import { formatDate } from '/@/utils/formatTime';
import { sizeTostr } from '/@/utils/extendMethods';
import textImgIcon from '/@/assets/icon/file-icon-text.png';
import defaultImgIcon from '/@/assets/icon/file-icon-default.png';
import imgIcon from '/@/assets/icon/file-icon-img.png';
import { EMsgType, EIdentity, IChattingRecord } from './type';

interface IState {
	serveType: number | null;
	Recver: string;
	chatUserID: string; // 用户ID
	msgTypes: EMsgType;
	uploadUrl: string;
	content: string;
	fileUrlPrefix: string;
	chattingRecordList: IChattingRecord[];
	self: Record<string, any>;
	isRetract: boolean;
	fileIcon: string;
	fileInfo: Record<string, any>;
}

const httpRequest = httpReqeustApi();

const state = reactive<IState>({
	serveType: null,
	Recver: '',
	chatUserID: '',
	msgTypes: EMsgType.text,
	uploadUrl: '',
	content: '',
	fileUrlPrefix: '',
	chattingRecordList: [], // 聊天记录
	self: {},
	isRetract: true,
	fileIcon: defaultImgIcon,
	fileInfo: {},
});

const fileSendMessage = (obj: { msgTypes: EMsgType; uploadUrl: string; fileInfo: Record<string, any>[] }) => {
	state.msgTypes = obj.msgTypes;
	state.uploadUrl = obj.uploadUrl;
	state.fileInfo = obj.fileInfo;
	sendMessageReq();
};
// 发送消息
const sendMessageReq = () => {
	console.log('sendMessageReq', state.msgTypes);
	if ((state.msgTypes === EMsgType.text && !state.content) || (state.msgTypes !== EMsgType.text && !state.uploadUrl)) {
		return;
	}
	let content: any = '';
	console.log('sendMessageReq', state.content);
	const params: Record<string, any> = {};
	params.Recver = state.Recver;
	params.Sender = state.chatUserID;
	params.optype = 'req';
	params.to_key = BASE_API.ENT_CODE;
	params.to_subkey = state.Recver;
	// 发到客服组
	if (!state.Recver) {
		params.MsgClassify = 1;
		params.Recver = BASE_API.ENT_CODE;
		params.to_subkey = '_Any_';
	}
	// value == 1 发送图片消息
	if (state.msgTypes === EMsgType.img) {
		params.ContentType = EMsgType.img;
		params.Message = state.uploadUrl;
		content = state.uploadUrl;
	} else if (state.msgTypes === EMsgType.text) {
		// 发送普通文字消息
		params.Message = Base64.encode(state.content);
		params.ContentType = EMsgType.text;
		content = state.content;
	} else if (state.msgTypes === EMsgType.file) {
		// 发送文件
		params.ContentType = EMsgType.file;
		params.Message = {
			link: state.uploadUrl,
			title: state.fileInfo.name,
			size: sizeTostr(state.fileInfo.size),
			status: '已上传',
		};
		const arr = state.uploadUrl.split('.');
		if (arr.length) {
			if (arr[arr.length - 1] === 'txt') {
				state.fileIcon = textImgIcon;
			} else if (['png', 'jpg'].includes(arr[arr.length - 1])) {
				state.fileIcon = imgIcon;
			} else {
				state.fileIcon = defaultImgIcon;
			}
		}
		params.Message.icon = state.fileIcon;
		content = params.Message;
	}

	// httpRequest.Post('sendIMReq', {}, params).then((res) => {
	// 	console.log('sendIMReq', res);
	// });
	console.log('send params:', params);
	ws.send(params);

	// 本地保存聊天记录
	const chattingRecord: IChattingRecord = {
		name: '我',
		time: formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS'),
		content: content,
		identity: EIdentity.Customer,
		ContentType: params.ContentType,
	};
	saveChattingRecord(chattingRecord);
	state.content = '';
	state.uploadUrl = '';
	nextTick(() => {
		scrollToBottom();
	});
	return;
};

// 随机ID
function setSessionId(len: number = 32) {
	const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
	const maxPos = chars.length;
	let pwd = '';
	for (var i = 0; i < len; i++) {
		pwd += chars.charAt(Math.floor(Math.random() * maxPos));
	}
	return pwd;
}

// 保存聊天记录
const saveChattingRecord = (chattingRecord: IChattingRecord) => {
	state.chattingRecordList.push(chattingRecord);
	const prefix = BASE_API.PROJECT_URI.slice(1);
	localStorage.setItem(prefix + '_chattingRecordList', JSON.stringify(state.chattingRecordList));
};

// 初始化
(() => {
	// 如果本地有UserID就直接取,没有就生成UserID
	if (!localStorage.getItem('chatUserID')) {
		const chatUserID = setSessionId();
		state.chatUserID = BASE_API.ENT_CODE + '-' + chatUserID;
		localStorage.setItem('chatUserID', BASE_API.ENT_CODE + '-' + chatUserID);
	} else {
		state.chatUserID = localStorage.getItem('chatUserID')!;
	}
	state.Recver = sessionStorage.getItem('Recver') || '';
	let isGroup = false;
	// 发到客服组
	console.log('Recver', state.Recver);
	if (!state.Recver) {
		isGroup = true;
	}
	ws.connect(state.chatUserID);
	ws.onOpen(state.chatUserID, isGroup);
	ws.recvData((onMessage) => {
		const res: Record<string, any> = JSON.parse(onMessage.data);
		console.log('监听WebSocket接受到服务器的消息事件。服务器返回的消息', res);
		if (res.Sender && res.Recver && res.optype !== 'notify') {
			// 为空时保持接受者ID
			if (!state.Recver) {
				state.Recver = res.Sender;
				sessionStorage.setItem('Recver', res.Sender);
			}

			let content = '';
			// 本地保存聊天记录
			if (res.Message && res.ContentType === EMsgType.text) {
				content = Base64.decode(res.Message) || '';
			} else if (res.Message && [EMsgType.img, EMsgType.file].includes(res.ContentType)) {
				content = res.Message;
			}
			const chattingRecord: IChattingRecord = {
				name: '客服',
				time: formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS'),
				content: content,
				identity: EIdentity.CustomerService,
				ContentType: res.ContentType,
			};
			saveChattingRecord(chattingRecord);

			nextTick(() => {
				scrollToBottom();
			});
		}
	});
	// 聊天记录内容
	const prefix = BASE_API.PROJECT_URI.slice(1);
	const localChatContentStr = localStorage.getItem(prefix + '_chattingRecordList');
	// 初始化历史数据
	if (localChatContentStr) {
		const localChatContent = JSON.parse(localChatContentStr);
		state.chattingRecordList = localChatContent || [];
	}
	// 本地保存聊天记录
	const chattingRecord: IChattingRecord = {
		name: '',
		time: formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS'),
		content: '',
		identity: EIdentity.StartCommunication,
		ContentType: EMsgType.text,
	};
	saveChattingRecord(chattingRecord);
	// 获取文件Url
	if (localStorage.getItem('setting')) {
		state.fileUrlPrefix = JSON.parse(localStorage.getItem('setting')!).ImagUrl;
	}
})();

onMounted(() => {
	nextTick(() => {
		scrollToBottom();
	});
});
onUnmounted(() => {
	ws.closeWebSocket();
});
const scrollToBottom = () => {
	const chattingRecordEl = document.querySelector('.dialog-box');
	if (chattingRecordEl) {
		chattingRecordEl.scrollTop = chattingRecordEl.scrollHeight;
	}
};
</script>
<style lang="scss" scoped>
.container {
	display: flex;
	justify-content: center;
	align-items: center;
	height: calc(100vh - 120px);
}
.chat-box {
	width: 800px;
	display: flex;
	background-color: var(--next-color-white);
	box-shadow: var(--el-box-shadow-light);
	.left {
		min-width: 560px;
		flex: 1;
		border-right: 1px solid #e6e8eb;
		.head {
			display: flex;
			justify-content: space-between;
			padding: 0px 10px;
			height: 44px;
			align-items: center;
			border-bottom: 1px solid #e6e8eb;
		}
		.dialog-box {
			height: 404px;
		}
	}
	.right {
		display: flex;
		flex-direction: column;
		align-items: center;
		padding-top: 40px;
		width: 240px;
		transition: width 0.5s;
		img {
			width: 18px;
			margin-right: 10px;
		}
		.avatar {
			width: 70px;
		}
		.title {
			font-size: 18px;
			margin-bottom: 25px;
		}
		.address,
		.domain-name {
			display: flex;
			width: 100%;
			margin-left: 20px;
			margin-bottom: 15px;
		}
	}
	.handler {
		border-top: 1px solid #e6e8eb;
		padding: 15px 15px 8px 15px;
		position: relative;
		.emoji-content {
			position: absolute;
			display: none;
			left: 10px;
			top: -190px;
			width: 360px;
			height: 180px;
			background-color: var(--next-color-white);
			overflow-y: auto;
			font-size: 20px;
			box-shadow: var(--el-box-shadow-light);

			.emoji {
				display: inline-flex;
				justify-content: center;
				width: 34px;
				height: 34px;
				cursor: pointer;
			}
		}
		.input {
			height: 50px;

			overflow-y: auto;
		}
		.tool-bar {
			display: flex;
			justify-content: space-between;
			.tool {
				display: flex;
				align-items: flex-end;
				img {
					width: 22px;
					cursor: pointer;
				}
				img:nth-child(2) {
					margin: 0 10px;
				}
			}
		}
	}
}
.dialog-box {
	width: 100%;
	background-color: var(--next-color-white);
	padding: 20px 15px;
	overflow-y: auto;
}
.not-chat {
	text-align: center;
	color: #909399;
	font-size: 12px;
}
.communication-time-box {
	text-align: center;
}
.communication-time {
	display: inline-block;
	margin: 24px 12px 0;
	padding: 5px 12px;
	font-size: 12px;
	line-height: 18px;
	color: #606266;
	border-radius: 4px;
	background: #f5f7fa;
}
.chat-item {
	margin-bottom: 16px;
	.title {
		margin-bottom: 4px;
		font-size: 12px;
		line-height: 12px;
		color: #a4a0aa;
		min-width: 66px;
	}
	.content {
		font-size: 14px;
		word-break: break-all;
		border-radius: 4px;
		border-radius: 0 8px 8px 8px;
		background: #eff1f7;
		white-space: pre-line;
		line-height: 22px;
		padding: 12px;
		max-width: 80%;
		display: inline-block;
	}
	.file {
		display: flex;
		border: 1px solid #ebeef5;
		width: 298px;
		height: 65px;
		background: #fff;
		border-radius: 8px 0 8px 8px;
		padding: 12px 8px 12px 12px;
		cursor: pointer;
		.el-image {
			// margin: 12px 8px 12px 12px;
			margin-right: 10px;
		}
		.info {
			width: calc(100% - 55px);
			.title {
				color: #303133;
				text-align: left;
				overflow: hidden;
				white-space: nowrap;
				text-overflow: ellipsis;
				width: 100%;
				margin-top: 3px;
				margin-bottom: 8px;
			}
			span {
				color: #909399;
				font-weight: 400;
				&.size {
					margin-right: 10px;
				}
			}
		}
	}
}
.customer {
	display: flex;
	flex-direction: column;
	align-items: flex-end;

	.content {
		border-radius: 8px 0px 8px 8px;
	}
}
.retract-right {
	cursor: pointer;
}
</style>
